package org.light.facade;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.light.domain.Domain;
import org.light.domain.Field;
import org.light.domain.ManyToMany;
import org.light.utils.DomainUtil;
import org.light.utils.StringUtil;
import org.light.utils.TypeUtil;
import org.light.wizard.ProjectWizard;

import net.sf.json.JSONObject;

/**
 * 
 * @author Jerry Shen 2021.1.29
 *
 */
public class CreateDomianFieldsWithSerialFacade extends HttpServlet {
	private static final long serialVersionUID = -598489528766854598L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public CreateDomianFieldsWithSerialFacade() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		processRequest(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		processRequest(request, response);
	}
	
	protected void processRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/plain;charset=UTF-8");
		PrintWriter out = response.getWriter();
		int serial = Integer.valueOf(StringUtil.nullTrim(request.getParameter("serial")));		
		String domainid = StringUtil.nullTrim(request.getParameter("domainid"));
		String domainidtype = StringUtil.nullTrim(request.getParameter("domainidtype"));		
		String domainidlength = StringUtil.nullTrim(request.getParameter("domainidlength"));
		String domainidlabel = StringUtil.nullTrim(request.getParameter("domainidlabel"));
		String domainidfixedname = StringUtil.nullTrim(request.getParameter("domainidfixedname"));
		String domainiddeny = StringUtil.nullTrim(request.getParameter("domainiddeny"));
		String domainname = StringUtil.nullTrim(request.getParameter("domainname"));
		String domainnametype = StringUtil.nullTrim(request.getParameter("domainnametype"));
		String domainnamelength = StringUtil.nullTrim(request.getParameter("domainnamelength"));
		String domainnamelabel = StringUtil.nullTrim(request.getParameter("domainnamelabel"));
		String domainnamefixedname = StringUtil.nullTrim(request.getParameter("domainnamefixedname"));
		String domainnamedeny = StringUtil.nullTrim(request.getParameter("domainnamedeny"));
		String activefield = StringUtil.nullTrim(request.getParameter("activefield"));
		String activefieldtype = StringUtil.nullTrim(request.getParameter("activefieldtype"));
		String activefieldlength = StringUtil.nullTrim(request.getParameter("activefieldlength"));
		String activefieldlabel = StringUtil.nullTrim(request.getParameter("activefieldlabel"));
		String activefieldfixedname = StringUtil.nullTrim(request.getParameter("activefieldfixedname"));
		String activefielddeny = StringUtil.nullTrim(request.getParameter("activefielddeny"));
		
		String [] fieldoriginalcatlog = request.getParameterValues("fieldoriginalcatlog[]");
		String [] fieldoriginalname = request.getParameterValues("fieldoriginalname[]");
		String [] fieldcatlog = request.getParameterValues("fieldcatlog[]");
		String [] field = request.getParameterValues("field[]");
		String [] fieldtype = request.getParameterValues("fieldtype[]");
		String [] fieldlength = request.getParameterValues("fieldlength[]");
		String [] fieldlabel = request.getParameterValues("fieldlabel[]");
		String [] fieldfixedname = request.getParameterValues("fieldfixedname[]");
		
		
		try {
			Domain domain0 = new Domain();
			Field fdomainid;
			if ("false".equalsIgnoreCase(domainiddeny)&&!StringUtil.isBlank(domainid)) {
				fdomainid = new Field(domainid,domainidtype);
				fdomainid.setLengthStr(domainidlength);
				fdomainid.setLabel(domainidlabel);
				if (!StringUtil.isBlank(domainidfixedname)&&!domainidfixedname.equals(domainid)) {
					fdomainid.setFixedName(domainidfixedname);
				}
				fdomainid.setSerial(-300L);
				domain0.setDomainId(fdomainid);				
			}
			Field fdomainname;
			if ("false".equalsIgnoreCase(domainnamedeny)&&!StringUtil.isBlank(domainname)) {
				fdomainname = new Field(domainname,domainnametype);
				fdomainname.setLengthStr(domainnamelength);
				fdomainname.setLabel(domainnamelabel);
				if (!StringUtil.isBlank(domainnamefixedname)&&!domainnamefixedname.equals(domainname)) {
					fdomainname.setFixedName(domainnamefixedname);
				}
				fdomainname.setSerial(-200L);
				domain0.setDomainName(fdomainname);
			}
			Field factive;
			if ("false".equalsIgnoreCase(activefielddeny)&&!StringUtil.isBlank(activefield)) {
				factive = new Field(activefield,activefieldtype);
				factive.setLengthStr(activefieldlength);
				factive.setLabel(activefieldlabel);
				if (!StringUtil.isBlank(activefieldfixedname)&&!activefieldfixedname.equals(activefield)) {
					factive.setFixedName(activefieldfixedname);
				}
				factive.setSerial(-100L);
				domain0.setActive(factive);
			}
			if (fieldcatlog!=null) {
				Set<String> fieldNames = new TreeSet<>();
				for (int i=0;i<fieldcatlog.length;i++) {
					Map<String,String> params = new TreeMap<>();
					params.put("fieldcatlog",fieldcatlog[i]);
					params.put("fieldname",field[i]);
					params.put("fieldtype",fieldtype[i]);
					params.put("fieldlength",fieldlength[i]);
					params.put("fieldlabel",fieldlabel[i]);
					params.put("fieldfixedname",fieldfixedname[i]);
					params.put("serial",""+(i*100));
					if ("manytomany".equals(fieldcatlog[i])) {
						ManyToMany mtm =  ProjectWizard.createNewManyToMany(domain0, params);
						domain0.addManyToMany(mtm);
					}else {
						if (!fieldNames.contains(field[i])) {
							Field f = ProjectWizard.createNewField(params);						
							fieldNames.add(field[i]);
							domain0.addField(f);
						}						
					}
				}
			}
			if (ExcelWizardFacade.getInstance()!=null&&(ExcelWizardFacade.getInstance().getDomains()==null||ExcelWizardFacade.getInstance().getDomains().size()<=serial)) {
				ExcelWizardFacade.getInstance().addDomain(domain0);
			}
			if (ExcelWizardFacade.getInstance()!=null && ExcelWizardFacade.getInstance().getDomains()!=null && ExcelWizardFacade.getInstance().getDomains().size()>serial) {
				Domain domain00 = ExcelWizardFacade.getInstance().getDomains().get(serial);
				List<Domain> dataDomains = DomainUtil.filterDataDomainList(
						ExcelWizardFacade.getInstance().getDataDomains(), domain00.getStandardName());
				List<Domain> dummyDb = domain00.getDummyDb();

				if ("false".equalsIgnoreCase(domainiddeny)&&!StringUtil.isBlank(domainid)) {
					fdomainid = new Field(domainid,domainidtype);
					fdomainid.setLengthStr(domainidlength);
					fdomainid.setLabel(domainidlabel);
					if (!StringUtil.isBlank(domainidfixedname)&&!domainidfixedname.equals(domainid)) {
						fdomainid.setFixedName(domainidfixedname);
					}
					fdomainid.setSerial(-300L);
					if (domain00.getDomainId()!=null) {
						fdomainid.setFieldValue(domain00.getDomainId().getFieldValue());
						for (Domain d : dataDomains) {
							Field did = (Field)fdomainid.clone();
							String value = d.getDomainId().getFieldValue();
							if (!StringUtil.isBlank(value)) did.setFieldValue(value);
							d.setDomainId(did);
						}
						for (Domain d : dummyDb) {
							Field did = (Field)fdomainid.clone();
							String value = d.getDomainId().getFieldValue();
							if (!StringUtil.isBlank(value)) did.setFieldValue(value);
							d.setDomainId(did);
						}
					}else {
						fdomainid.setFieldValue("1");
						for (int i=0;i<dataDomains.size();i++) {
							Field did = (Field)fdomainid.clone();
							String value = ""+(i+1);
							did.setFieldValue(value);
							dataDomains.get(i).setDomainId(did);
						}
						for (int i=0;i<dummyDb.size();i++) {
							Field did = (Field)fdomainid.clone();
							String value = ""+(i+1);
							did.setFieldValue(value);
							dummyDb.get(i).setDomainId(did);
						}
					}
					domain00.setDomainId(fdomainid);				
				} else {
					if (domain00.getDomainId()!=null) {					
						domain00.removeFieldFromAll(domain00.getDomainId().getFieldName(), "domainid");
						for (Domain d : dataDomains) {
							if (d.getDomainId() != null) d.removeFieldFromAll(d.getDomainId().getFieldName(), "domainid");
						}
					}
				}
				if ("false".equalsIgnoreCase(domainnamedeny)&&!StringUtil.isBlank(domainname)) {
					fdomainname = new Field(domainname,domainnametype);
					fdomainname.setLengthStr(domainnamelength);
					fdomainname.setLabel(domainnamelabel);
					if (!StringUtil.isBlank(domainnamefixedname)&&!domainnamefixedname.equals(domainname)) {
						fdomainname.setFixedName(domainnamefixedname);
					}
					fdomainname.setSerial(-200L);
					if (domain00.getDomainName()!=null) {
						fdomainname.setFieldValue(domain00.getDomainName().getFieldValue());
						for (Domain d : dataDomains) {
							Field dname = (Field)fdomainname.clone();
							String value = d.getDomainName().getFieldValue();
							if (!StringUtil.isBlank(value)) dname.setFieldValue(value);
							d.setDomainName(dname);
						}
						for (Domain d : dummyDb) {
							Field dname = (Field)fdomainname.clone();
							String value = d.getDomainName().getFieldValue();
							if (!StringUtil.isBlank(value)) dname.setFieldValue(value);
							d.setDomainName(dname);
						}
					}else {
						fdomainname.setFieldValue("");
						for (int i=0;i<dataDomains.size();i++) {
							Field dname = (Field)fdomainname.clone();
							String value = dname.getFieldName() +(i+1);
							dname.setFieldValue(value);
							dataDomains.get(i).setDomainName(dname);
						}
						for (int i=0;i<dummyDb.size();i++) {
							Field dname = (Field)fdomainname.clone();
							String value = dname.getFieldName() +(i+1);
							dname.setFieldValue(value);
							dummyDb.get(i).setDomainName(dname);
						}
					}				
					domain00.setDomainName(fdomainname);
				} else {
					if (domain00.getDomainName()!=null) {
						domain00.removeFieldFromAll(domain00.getDomainName().getFieldName(), "domainname");
						for (Domain d : dataDomains) {
							if (d.getDomainName() != null) d.removeFieldFromAll(d.getDomainName().getFieldName(), "domainname");
						}
					}
				}
				if ("false".equalsIgnoreCase(activefielddeny)&&!StringUtil.isBlank(activefield)) {
					factive = new Field(activefield,activefieldtype);
					factive.setLengthStr(activefieldlength);
					factive.setLabel(activefieldlabel);
					if (!StringUtil.isBlank(activefieldfixedname)&&!activefieldfixedname.equals(activefield)) {
						factive.setFixedName(activefieldfixedname);
					}
					factive.setSerial(-100L);				
					if (domain00.getActive()!=null) {
						factive.setFieldValue(domain00.getActive().getFieldValue());
						for (Domain d : dataDomains) {
							Field dactive = (Field)factive.clone();
							String value = d.getActive().getFieldValue();
							if (!StringUtil.isBlank(value)) dactive.setFieldValue(value);
							d.setActive(dactive);
						}
						for (Domain d : dummyDb) {
							Field dactive = (Field)factive.clone();
							String value = d.getActive().getFieldValue();
							if (!StringUtil.isBlank(value)) dactive.setFieldValue(value);
							d.setActive(dactive);
						}
						domain00.setActive(factive);
					}else {
						domain00.setActive(factive);
						factive.setFieldValue("true");
						for (Domain d : dataDomains) {
							Field dactive = (Field)factive.clone();
							dactive.setFieldValue(domain00.getDomainActiveStr());
							d.setActive(dactive);
						}
						for (Domain d : dummyDb) {
							Field dactive = (Field)factive.clone();
							dactive.setFieldValue(domain00.getDomainActiveStr());
							d.setActive(dactive);
						}
					}				
				} else {
					if (domain00.getActive()!=null) {
						domain00.removeFieldFromAll(domain00.getActive().getFieldName(), "activefield");
						for (Domain d : dataDomains) {
							if (d.getActive() != null) d.removeFieldFromAll(d.getActive().getFieldName(), "activefield");
						}
					}
				}
				if (fieldcatlog!=null) {
					for (int i=0;i<fieldcatlog.length;i++) {
						if (StringUtil.isBlank(fieldoriginalcatlog[i])&&StringUtil.isBlank(fieldoriginalname[i])){
							Map<String,String> params = new TreeMap<>();
							params.put("fieldcatlog",fieldcatlog[i]);
							params.put("fieldname",field[i]);
							params.put("fieldtype",fieldtype[i]);
							params.put("fieldlength",fieldlength[i]);
							params.put("fieldlabel",fieldlabel[i]);
							params.put("fieldfixedname",fieldfixedname[i]);
							params.put("serial",""+(i*100));
							if ("manytomany".equals(fieldcatlog[i])) {
								ManyToMany mtm =  ProjectWizard.createNewManyToMany(domain00, params);
								mtm.setValues("");
								domain00.addManyToMany(mtm);
								for (Domain d: domain00.getDummyDb()) {
									d.addManyToMany(mtm);
								}
								for (Domain dd: dataDomains) {
									dd.addManyToMany(mtm);
								}
							}else {
								Field f = ProjectWizard.createNewField(params);	
								f.setFieldValue(TypeUtil.findEmptyTypeValueString(f.getFieldType()));
								domain00.addField(f);
								for (Domain d: domain00.getDummyDb()) {
									d.addField(f);
								}
								for (Domain dd: dataDomains) {
									dd.addField(f);
								}
							}
						} else {
							List<Domain> domainList = ExcelWizardFacade.getInstance().getDomains();
							domain00.updateFieldForAll(fieldoriginalcatlog[i], fieldoriginalname[i], fieldcatlog[i], field[i], fieldtype[i], fieldlength[i], fieldlabel[i], fieldfixedname[i], domainList);
							for (Domain d : dataDomains) {
								d.updateFieldForAll(fieldoriginalcatlog[i], fieldoriginalname[i], fieldcatlog[i], field[i], fieldtype[i], fieldlength[i], fieldlabel[i], fieldfixedname[i], domainList);
							}
						}
					}
				}
			}
		} catch(Exception e) {
			e.printStackTrace();
		}

		try {
			Map<String, Object> result = new TreeMap<String, Object>();
			result.put("success", true);
			result.put("data", null);
			out.print(JSONObject.fromObject(result));
		} catch(Exception e) {
			e.printStackTrace();
		}	
	}
}
